#include "base/scoped_ptr.h"
#include "base/singleton.h"

#include "core/def.h"
#include "core/style.h"
#include "core/widget.h"

#include "win/builder.h"
#include "win/factory.h"

#include "util/string.h"

namespace win
{

    core::StWidget* Builder::Parse(const wchar_t *file)
    {
        if (util::String::IsEmpty<wchar_t>(file))
        {
            return 0;
        }

        base::scoped_array<BYTE> byte_;
        Cache* cache = base::Singleton<Factory>::Instance().GetCache();
        if (!cache)
        {
            return 0;
        }

        if (!cache->GetBinaryResource(file, byte_.accept(), 0, TRUE))
        {
            return 0;
        }

        XmlDocument doc;
        if (!doc.Parse((const char *)byte_.get()) || doc.Error())
        {
            return 0;
        }

        XmlElement* root = doc.RootElement();
        if (!root)
        {
            return 0;
        }

        const char* value = root->Value();
        if (!value || strcmp(value, "widget") != 0)
        {
            return 0;
        }

        BuildHeader(root);
        return BuildBody(root);
    }

    core::StWidget* Builder::ParseText(const wchar_t* text)
    {
        return 0;
    }

    BOOL Builder::BuildHeader(XmlElement* root)
    {
        if (!root || !style_cache_)
        {
            return FALSE;
        }

        XmlElement* head = root->FirstChildElement("head");
        if (!head)
        {
            return FALSE;
        }

        XmlElement* link = head->FirstChildElement("link");
        while (link)
        {
            if (strcmp(link->Attribute("type"), "text/css") != 0)
            {
                link = link->NextSiblingElement("link");
                continue;
            }

            const char* file = link->Attribute("href");
            std::wstring path = util::String::UTF8ToUnicode(file);

            base::scoped_array<BYTE> byte_;
            Cache* cache = base::Singleton<Factory>::Instance().GetCache();
            if (!cache)
            {
                return FALSE;
            }

            if (cache->GetBinaryResource(path.c_str(), byte_.accept(), 0, TRUE))
            {
                style_cache_->Parse((const char *)byte_.get());
            }

            link = link->NextSiblingElement("link");
        }

        return TRUE;
    }

    core::StWidget* Builder::BuildBody(XmlElement* root)
    {
        if (!root)
        {
            return FALSE;
        }

        XmlElement* body = root->FirstChildElement("body");
        if (!body)
        {
            return FALSE;
        }

        return FALSE;
    }
}